/*
//              INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license  agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in  accordance  with the terms of that agreement.
//    Copyright (c) 2006-2007 Intel Corporation. All Rights Reserved.
//
*/
#include "umc_defs.h"
#if defined (UMC_ENABLE_DV50_VIDEO_DECODER)

#ifndef __UMC_DV100_DECODER_H
#define __UMC_DV100_DECODER_H

#include "umc_video_decoder.h"
#include "ippdefs.h"
#include "vm_thread.h"

namespace UMC
{

enum DV100_SystemType
{
    SystemUnknown               = 0,
    System1080                  = 1,
    System1080_60i              = 2,
    System1080_50i              = 3,
    System720_60p               = 4,
    System720_50p               = 5
};

enum
{
    SYSTEM_720_WIDTH                    = 1280,
    SYSTEM_720_WIDTH_NOT_STRETCHED      = 960,
    SYSTEM_720_HEIGHT                   = 720,
    SYSTEM_1080_WIDTH                   = 1920,
    SYSTEM_1080_60I_WIDTH_NOT_STRETCHED = 1280,
    SYSTEM_1080_50I_WIDTH_NOT_STRETCHED = 1440,
    SYSTEM_1080_HEIGHT                  = 1080
};

class THREAD_ID;

void QuarterResolutionStoreYCrCb422ToYCbCr422_DV100_16s8u_P3C2R          (const Ipp16s* pSrc,
                                                                                Ipp8u *pDst[10],
                                                                                Ipp32s dstStep);
void Resolution8x8To4x4To2x2StoreYCrCb422ToYCbCr422_DV100_16s8u_P3C2R    (const Ipp16s* pSrc,
                                                                                Ipp8u *pDst[10],
                                                                                Ipp32s dstStep);
void DCOnlyStoreYCrCb422ToYCbCr422_DV100_16s8u_P3C2R                     (const Ipp16s* pSrc,
                                                                                Ipp8u *pDst[10]/*,
                                                                                Ipp32s dstStep*/);
void Resolution8x8To8x4StoreYCrCb422ToYCbCr422_DV100_16s8u_P3C2R         (const Ipp16s* pSrc,
                                                                                Ipp8u *pDst[10],
                                                                                Ipp32s dstStep);
void Resolution8x8To8x2StoreYCrCb422ToYCbCr422_DV100_16s8u_P3C2R         (const Ipp16s* pSrc,
                                                                                Ipp8u *pDst[10],
                                                                                Ipp32s dstStep);
void tst_YCrCb422ToYCbCr422_10HalvesMB16x8_DV100_16s8u_P3C2R             (const Ipp16s* pSrc,
                                                                                Ipp8u *pDst[10],
                                                                                Ipp32s dstStep);

class DV100VideoDecoder : public VideoDecoder
{
public:
    DV100VideoDecoder(void);
    ~DV100VideoDecoder(void);

    // Initialize DV decoder
    virtual Status      Init            (BaseCodecParams *init);

    // Close decoder
    virtual Status      Close           ();

    // Decode next frame
    virtual Status      GetFrame        (MediaData *pInData, MediaData *pOutData);

    // Get video stream information, valid after initialization
    virtual Status    GetInfo         (BaseCodecParams* info);

    // Get decoder performance
    virtual Status      GetPerformance  (Ipp64f *perf);

    // Reset decoder into initial state
    virtual Status      Reset           ();

    // reset skip frame counter
    virtual Status      ResetSkipCount  (){return UMC_ERR_NOT_IMPLEMENTED;};

    // increment skip frame counter
    virtual Status      SkipVideoFrame  (Ipp32s){return UMC_ERR_NOT_IMPLEMENTED;};

    // get skip frame counter statistic
    virtual Ipp32u    GetNumOfSkippedFrames  (){return 0;};

protected:
    Status GetSystemSubtype();

    void Store_System720_60p_Segment(Ipp16s* pDecodedVideoSegment, Ipp32s nChannelNum, Ipp32s nDIFSeqNum, Ipp32s nVideoSegmentNum);
    void Store_System1080_50i_Segment(Ipp16s* pDecodedVideoSegment, Ipp32s nChannelNum, Ipp32s nDIFSeqNum, Ipp32s nVideoSegmentNum);
    void Store_System1080_60i_Segment(Ipp16s* pDecodedVideoSegment, Ipp32s nChannelNum, Ipp32s nDIFSeqNum, Ipp32s nVideoSegmentNum);

    DV100_SystemType m_System;
    Ipp32u *m_pHuffTable;
    MemID   m_DCTBlocksBufferMID;
    Ipp16s **m_ppDecodedDCTBlocks;
    Ipp8u  *m_pDestination;                  // (Ipp8u *) pointer to destination image
    Ipp8u  *m_pStreamStart;                  // (Ipp8u *) pointer to start of encoded bit stream
    MemID  m_InternalFrameBufferMID;
    Ipp8u  *m_pInternalFrameBuffer;
    Ipp32s m_nWidth;          // width
    Ipp32s m_nHeight;         // height
    Ipp32s m_nDestPitch;      // pitch
    Ipp32s m_nSystem720_LastDecodedChannel;

    Ipp32s  m_nNumberOfThreads;
    vm_event m_Quit;                                            // (vm_event) event to quit
    vm_thread *m_pThreads;                                      // (vm_thread *) pointer to array of thread(s)
    vm_event *m_pStartEvents;                                   // (vm_event *) pointer to array of event(s)
    vm_event *m_pStopEvents;                                    // (vm_event *) pointer to array of event(s)
    THREAD_ID *m_pThreadsID;                                    // (THREAD_ID *) pointer to array of thread's ID

    bool m_bInitSuccess;                                        // True, if Init() success

    Ipp32s m_shortCutModeFlag;

    // Additional thread working routine
    static Ipp32u VM_THREAD_CALLCONVENTION ThreadWorkingRoutine(void *lpv);

    static const Ipp16s LumaQuantizeMatrix_1080System[];
    static const Ipp16s ChromaQuantizeMatrix_1080System[];
    static const Ipp16s LumaQuantizeMatrix_720System[];
    static const Ipp16s ChromaQuantizeMatrix_720System[];
    static const Ipp32s QuantizationSteps[];

    void DecomressDIFSequences(Ipp32s nThreadNum);
};

}//namespace UMC

#endif //__UMC_DV100_DECODER_H

#endif //(UMC_ENABLE_DVHD_VIDEO_DECODER)
